#include <stdio.h>
#include <memory.h>
#include "hal/hal_io.h"
#include "hal_mcu.h"
#include "hal/hal_uart.h"
#include "userLog.h"

#define HAL_MCU_GET_TOTAL_LEN(s32DataLen) ((s32DataLen) + 2 + 2)

static T_INT32 gss32UartChn = -1;

static T_UINT8 _HAL_MCU_CRC(T_UINT8 *pu8Data, T_INT32 nLen)
{
	int i;
	T_UINT8 u8CRC = 0;

	for (i = 0; i < nLen; i++)
	{
		u8CRC ^= pu8Data[i];
	}

	return u8CRC;
}

static T_INT32 _HAL_MCU_SetCrc(HAL_MCU_HEAD_S *pHead, T_INT32 s32BodyLen)
{
	T_UINT8 u8CRC = 0;

	if (!pHead)
	{
		return -1;
	}

	u8CRC = _HAL_MCU_CRC((T_UINT8 *)(&pHead->u16DataLen), s32BodyLen + 1 + 2);
	pHead->au8Data[s32BodyLen] = u8CRC;
	return 0;
}

static T_INT32 _HAL_MCU_Send(T_UINT8 *pu8Buf, T_INT32 nBufLen)
{
	return HAL_UART_Send(gss32UartChn, pu8Buf, nBufLen);
}

static T_INT32 _HAL_MCU_Recv(T_UINT8 *pu8Buf, T_INT32 nBufLen)
{
	return HAL_UART_Recv(gss32UartChn, pu8Buf, nBufLen);
}

static T_INT32 _HAL_MCU_SendCmdAck(T_UINT8 u8Cmd, T_UINT8 *pu8Data, T_INT32 nLen)
{
	int s32RetLen = 0;
	int s32TotalLen = 0;
	T_UINT8 au8Cmd[64];
	HAL_MCU_HEAD_S *pHead = (HAL_MCU_HEAD_S *)au8Cmd;

	memset((void *)au8Cmd, 0, sizeof(au8Cmd));

	pHead->u16HeadFlag = COMM_HostToNetS(HAL_MCU_HEAD_FLAG);
	pHead->u16DataLen = COMM_HostToNetS(nLen + 2);
	pHead->u8Cmd = u8Cmd;
	memcpy(pHead->au8Data, pu8Data, nLen);
	_HAL_MCU_SetCrc(pHead, nLen);
	s32TotalLen = HAL_MCU_GET_TOTAL_LEN(nLen + 2);
	_HAL_MCU_Send((T_UINT8 *)pHead, s32TotalLen);
	// LOG_INFO("To Mcu:");
	// hzlog_info(userLog, pHead, s32TotalLen);

	memset((void *)au8Cmd, 0, sizeof(au8Cmd));
	s32RetLen = _HAL_MCU_Recv(au8Cmd, sizeof(au8Cmd));
	if (s32RetLen <= 0)
	{
		// LOG_ERROR("_HAL_MCU_Recv() error");
		return -1;
	}
	// LOG_INFO("mcu uart recv len:%d", s32RetLen);
	// hzlog_info(userLog, au8Cmd, s32RetLen);

	return 0;
}

T_INT32 HAL_MCU_SetIo(T_UINT8 u8IoChn, T_UINT8 u8Level)
{
	T_UINT8 u8Io = 0;

	u8Io = u8IoChn << 4 | (u8Level & 0x0f);
	return _HAL_MCU_SendCmdAck((T_UINT8)HAL_MCU_CMD_IO_OUT, &u8Io, 1);
}

T_INT32 HAL_MCU_Init(void)
{
	T_INT32 s32Ret = 0;

	s32Ret = HAL_UART_Probe(HAL_UART_APP_NAME_MCU);
	if (s32Ret < 0)
	{
		LOG_ERROR("HAL_UART_Probe() for %s error", HAL_UART_APP_NAME_MCU);
		return -1;
	}
	gss32UartChn = s32Ret;
	LOG_INFO("mcu Uart in chn:%d", gss32UartChn);

	return 0;
}

T_INT32 HAL_MCU_DeInit(void)
{
	return 0;
}
